/*
 * Teknei 2014 - All rights reserved
 */
package com.teknei.acabus.core.controller;

import java.io.Serializable;
import java.util.LinkedList;
import java.util.List;
import java.util.Map;

import javax.annotation.PostConstruct;
import javax.ejb.EJB;
import javax.enterprise.context.SessionScoped;
import javax.inject.Named;
import javax.servlet.http.HttpServletRequest;

import org.primefaces.model.menu.DefaultMenuItem;
import org.primefaces.model.menu.DefaultMenuModel;
import org.primefaces.model.menu.MenuModel;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import com.teknei.acabus.FacadeException;
import com.teknei.acabus.core.common.MessageConstants;
import com.teknei.acabus.core.common.NavigationConstants;
import com.teknei.acabus.core.entities.NavigationChild;
import com.teknei.acabus.core.entities.NavigationParent;
import com.teknei.acabus.core.entities.Role;
import com.teknei.acabus.core.facade.NavigationFacade;
import com.teknei.acabus.core.singleton.NavigationSingleton;

/**
 * Controller for Navigation
 * @author Jorge Amaro
 * @version 1.0
 * @since 1.0
 *
 */
@Named("nav_controller")
@SessionScoped
public class NavigationController extends GenericController implements
		Serializable {

	/**
	 * 
	 */
	private static final long serialVersionUID = 1L;
	private static final Logger LOG = LoggerFactory
			.getLogger(NavigationController.class);
	private List<NavigationParent> listParents;
	private List<NavigationChild> listChilds;
	private NavigationParent selected;
	private boolean childsPresent;
	private NavigationChild child;
	private MenuModel menuModel;
	private List<Role> listRoles;

	@EJB
	private transient NavigationFacade facadeNavigation;
	@EJB
	private NavigationSingleton navigationSingleton;

	/**
	 * PostConstruct method. Initialize items
	 */
	@PostConstruct
	public void postConstruct() {
		try {
			HttpServletRequest request = (HttpServletRequest) getFacesContext()
					.getExternalContext().getRequest();
			listRoles = new LinkedList<Role>();
			for(Role role : navigationSingleton.getListRoles()){
				if(request.isUserInRole(role.getRoleName())){
					listRoles.add(role);
				}
			}
			listParents = facadeNavigation.findNavigationParents(listRoles);
			for (NavigationParent parent : listParents) {
				if (parent.getRoot() == 1) {
					selected = parent;
					break;
				}
			}
			listChilds = facadeNavigation.findNavigationChilds(listRoles, selected.getIdParent());
			initMenuModel();
		} catch (FacadeException e) {
			super.addErrorMessage(MessageConstants.MESSAGE_ERROR_NAVIGATION);
		}
	}

	/**
	 * Finds the url and initialize the menu
	 */
	public void searchForURLNavigation() {
		Map<String, Object> map = getFacesContext().getExternalContext()
				.getRequestMap();
		NavigationParent parent = (NavigationParent) map.get("parent");
		if (parent == null) {
			return;
		}
		NavigationChild child = (NavigationChild) map.get("child");
		this.selected = parent;
		this.child = child;
		initMenu();
	}

	/**
	 * Initialize the menu
	 */
	private void initMenu() {
		if (child == null) {
			listChilds = null;
			initMenuModel();
		} else {
			try {
				listChilds = facadeNavigation.findNavigationChilds(selected
						.getIdParent());
			} catch (FacadeException e) {
				super.addErrorMessage(MessageConstants.MESSAGE_ERROR_NAVIGATION);
			}
			initMenuModelChild();
		}
	}

	/**
	 * Initialize the menu model for breadcumb
	 */
	private void initMenuModel() {
		menuModel = new DefaultMenuModel();
		DefaultMenuItem item0 = new DefaultMenuItem();
		item0.setValue("Inicio");
		item0.setOutcome("nav_root");
		DefaultMenuItem item1 = new DefaultMenuItem();
		item1.setValue(selected.getText());
		item1.setOutcome(selected.getOutcome());
		menuModel.addElement(item0);
		menuModel.addElement(item1);
	}

	/**
	 * Initialize the menu model for breadcumb
	 */
	private void initMenuModelChild() {
		menuModel = new DefaultMenuModel();
		DefaultMenuItem item0 = new DefaultMenuItem();
		item0.setValue("Inicio");
		item0.setOutcome("nav_root");
		DefaultMenuItem item1 = new DefaultMenuItem();
		item1.setValue(selected.getText());
		item1.setOutcome(selected.getOutcome());
		DefaultMenuItem item2 = new DefaultMenuItem();
		item2.setValue(child.getText());
		item2.setOutcome(child.getOutcome());
		menuModel.addElement(item0);
		menuModel.addElement(item1);
		menuModel.addElement(item2);
	}

	/**
	 * Navigates based on url
	 * @return the action
	 */
	public String navigate() {
		try {
			listChilds = facadeNavigation.findNavigationChilds(selected
					.getIdParent());
			initMenuModel();
			return selected.getOutcome();
		} catch (FacadeException e) {
			super.addErrorMessage(MessageConstants.MESSAGE_ERROR_NAVIGATION);
			return NavigationConstants.NAVIGATION_SAME_PAGE;
		}
	}

	/**
	 * Navigation for child elements
	 * @return the action
	 */
	public String subNavigate() {
		initMenuModelChild();
		return child.getOutcome();
	}

	/**
	 * @return the listParents
	 */
	public List<NavigationParent> getListParents() {
		return listParents;
	}

	/**
	 * @param listParents
	 *            the listParents to set
	 */
	public void setListParents(List<NavigationParent> listParents) {
		this.listParents = listParents;
	}

	/**
	 * @return the listChilds
	 */
	public List<NavigationChild> getListChilds() {
		return listChilds;
	}

	/**
	 * @param listChilds
	 *            the listChilds to set
	 */
	public void setListChilds(List<NavigationChild> listChilds) {
		this.listChilds = listChilds;
	}

	/**
	 * @return the selected
	 */
	public NavigationParent getSelected() {
		return selected;
	}

	/**
	 * @param selected
	 *            the selected to set
	 */
	public void setSelected(NavigationParent selected) {
		this.selected = selected;
	}

	/**
	 * @return the facadeNavigation
	 */
	public NavigationFacade getFacadeNavigation() {
		return facadeNavigation;
	}

	/**
	 * @param facadeNavigation
	 *            the facadeNavigation to set
	 */
	public void setFacadeNavigation(NavigationFacade facadeNavigation) {
		this.facadeNavigation = facadeNavigation;
	}

	/**
	 * @return the childsPresent
	 */
	public boolean isChildsPresent() {
		if (listChilds == null || listChilds.isEmpty()) {
			childsPresent = false;
		} else {
			childsPresent = true;
		}
		return childsPresent;
	}

	/**
	 * @param childsPresent
	 *            the childsPresent to set
	 */
	public void setChildsPresent(boolean childsPresent) {
		this.childsPresent = childsPresent;
	}

	/**
	 * @return the child
	 */
	public NavigationChild getChild() {
		return child;
	}

	/**
	 * @param child
	 *            the child to set
	 */
	public void setChild(NavigationChild child) {
		this.child = child;
	}

	/**
	 * @return the menuModel
	 */
	public MenuModel getMenuModel() {
		return menuModel;
	}

	/**
	 * @param menuModel
	 *            the menuModel to set
	 */
	public void setMenuModel(MenuModel menuModel) {
		this.menuModel = menuModel;
	}

}
